/*
 * Copyright 2012 Alan Burlison, alan@bleaklow.com.  All rights reserved.
 * Use is subject to license terms.  See LICENSE.txt for details.
 */

/*
 * Serial IO management for the first USART.  Allows C stdio functions to be
 * used, e.g. printf(), scanf() etc.  Define BAUD to specify the required baud
 * rate before including this file, otherwise it defaults to 57600 baud.
 * See avr-libc <util/setbaud.h>.
 */

#ifndef serial_h
#define	serial_h

#include <stdint.h>
#include <stdio.h>
#include "utils.h"

#ifdef	__cplusplus
extern "C" {
#endif

// Serial input/output modes.
// Text mode: line buffered, echo input, handle backspace, map NL to CR/NL.
// Binary mode: unbuffered, no echoing, no backspace, no NL mapping.
#define SERIAL_IN_RAW   0x00
#define SERIAL_OUT_RAW  0x00
#define SERIAL_IN_TEXT  0x01
#define SERIAL_OUT_TEXT 0x02
#define SERIAL_RAW      (SERIAL_IN_RAW | SERIAL_OUT_RAW)
#define SERIAL_TEXT     (SERIAL_IN_TEXT | SERIAL_OUT_TEXT)

// Default output buffer size.
#ifndef SERIAL_OBUFSZ
#define SERIAL_OBUFSZ 80
#endif

// Default input buffer size.
#ifndef SERIAL_IBUFSZ
#define SERIAL_IBUFSZ 80
#endif

// Default baud rate.
#ifndef BAUD
#define BAUD 57600
#endif
#include <util/setbaud.h>

// Start the USART in the required mode.
extern void serial_start(uint8_t iomode,
  uint8_t ubrrh, uint8_t ubrrl, uint8_t use2x,
  FILE **in, FILE **out);

// Start the USART in the required mode running at BAUD.
#define serial_start_baud(MODE, IN, OUT) \
  serial_start(MODE, UBRRH_VALUE, UBRRL_VALUE, USE_2X, IN, OUT)

// Start the USART in the required mode, connecting to stdin, stdout & stderr.
extern void serial_start_stdio(uint8_t iomode,
  uint8_t ubrrh, uint8_t ubrrl, uint8_t use2x);

// Start the USART in the required mode, connecting to stdin, stdout & stderr
// and running at BAUD.
#define serial_start_stdio_baud(MODE) \
  serial_start_stdio(MODE, UBRRH_VALUE, UBRRL_VALUE, USE_2X)

// Stop the USART.
extern void serial_stop(void);

// Return the number of input characters available.
extern int serial_input_chars(void);

// Return the number of input lines available.
extern int serial_input_lines(void);

#ifdef	__cplusplus
}
#endif

#endif	/* serial_h */
